/*
 * Created by SharpDevelop.
 * User: phtrung
 * Date: 7/10/2008
 * Time: 9:05 AM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace QuickStartApp
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public class MainForm : System.Windows.Forms.Form
	{
		private System.ComponentModel.IContainer components;
		private System.Windows.Forms.Button button3;
		private System.Windows.Forms.Button button2;
		private System.Windows.Forms.Button button1;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.ComboBox text;
		private System.Windows.Forms.ContextMenu contextMenu1;
		private System.Windows.Forms.Panel panel2;
		private System.Windows.Forms.Panel panel1;
		private System.Windows.Forms.FolderBrowserDialog browser;
		private System.Windows.Forms.CheckedListBox list;
		private System.Windows.Forms.ToolTip toolTip1;
		private System.Windows.Forms.MenuItem menuItem1;
		
		ListBox applist = new ListBox();
		ArrayList resultDir = new ArrayList();
		Thread currentThread;
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			currentThread = new Thread(new ThreadStart(doSearch));
			//
			// TODO: Add constructor code after the InitializeComponent() call.
			//
		}
		
		[STAThread]
		public static void Main(string[] args)
		{
			Application.Run(new MainForm());
		}
		
		#region keycode
		const int WM_SETHOTKEY = 50;
		const int WM_SHOWWINDOW = 24;
		const int HK_SHIFTA = 321;
		// Shift + A
		const int HK_SHIFTB = 322;
		// Shift + B
		const int HK_CONTROLA = 577;
		// Control + A
		const int HK_ALTZ = 1114;

		
		
		const int VK_Alt = 18;
		const int VK_Tab = 9;
		const int VK_Backspace = 8;
		
		const int VK_Ctrl = 17;
		const int VK_V = 86;
		
		const int KEYEVENTF_EXTENDEDKEY = 1;
		const int KEYEVENTF_KEYUP = 2;
		#endregion
		
		#region API functions
		[DllImport("user32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);
        
        [DllImport("user32.dll")]
        public static extern int ShowWindow(int hWnd, int nCmdShow);
        
        [DllImport("user32.dll")]
        public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam);	
        
        [DllImport("user32.dll")]
        public static extern int SetActiveWindow(int hWnd );
		
        [DllImport("user32.dll")]
        public static extern int SetFocus(int hWnd );
        
        [DllImport("user32.dll", EntryPoint="DefWindowProcA")]
   		private static extern int DefWindowProc(int hwnd, int wMsg, int wParam, int lParam);
		
   		[DllImport("user32.dll")]
    	private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
    	
    	[DllImport("user32.dll")]
    	private static extern int SetForegroundWindow(int hWnd );
    	
    	[DllImport("user32.dll")]
		private static extern int GetAsyncKeyState(int nVirtKey );
    	#endregion	
		
		#region Windows Forms Designer generated code
		/// <summary>
		/// This method is required for Windows Forms designer support.
		/// Do not change the method contents inside the source code editor. The Forms designer might
		/// not be able to load this method if it was changed manually.
		/// </summary>
		private void InitializeComponent() {
			this.components = new System.ComponentModel.Container();
			System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(MainForm));
			this.menuItem1 = new System.Windows.Forms.MenuItem();
			this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
			this.list = new System.Windows.Forms.CheckedListBox();
			this.browser = new System.Windows.Forms.FolderBrowserDialog();
			this.panel1 = new System.Windows.Forms.Panel();
			this.panel2 = new System.Windows.Forms.Panel();
			this.contextMenu1 = new System.Windows.Forms.ContextMenu();
			this.text = new System.Windows.Forms.ComboBox();
			this.groupBox1 = new System.Windows.Forms.GroupBox();
			this.button1 = new System.Windows.Forms.Button();
			this.button2 = new System.Windows.Forms.Button();
			this.button3 = new System.Windows.Forms.Button();
			this.panel1.SuspendLayout();
			this.groupBox1.SuspendLayout();
			this.SuspendLayout();
			// 
			// menuItem1
			// 
			this.menuItem1.Index = 0;
			this.menuItem1.Text = "Exit";
			this.menuItem1.Click += new System.EventHandler(this.MenuItem1Click);
			// 
			// list
			// 
			this.list.Dock = System.Windows.Forms.DockStyle.Top;
			this.list.HorizontalScrollbar = true;
			this.list.Location = new System.Drawing.Point(3, 16);
			this.list.Name = "list";
			this.list.Size = new System.Drawing.Size(194, 139);
			this.list.TabIndex = 11;
			this.list.KeyUp += new System.Windows.Forms.KeyEventHandler(this.ListKeyUp);
			// 
			// panel1
			// 
			this.panel1.Controls.Add(this.button2);
			this.panel1.Controls.Add(this.button3);
			this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.panel1.Location = new System.Drawing.Point(3, 155);
			this.panel1.Name = "panel1";
			this.panel1.Size = new System.Drawing.Size(194, 61);
			this.panel1.TabIndex = 21;
			// 
			// panel2
			// 
			this.panel2.BackColor = System.Drawing.Color.Transparent;
			this.panel2.Location = new System.Drawing.Point(8, 0);
			this.panel2.Name = "panel2";
			this.panel2.Size = new System.Drawing.Size(40, 16);
			this.panel2.TabIndex = 5;
			this.panel2.Click += new System.EventHandler(this.Panel2Click);
			// 
			// contextMenu1
			// 
			this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
						this.menuItem1});
			// 
			// text
			// 
			this.text.ContextMenu = this.contextMenu1;
			this.text.Dock = System.Windows.Forms.DockStyle.Top;
			this.text.Location = new System.Drawing.Point(0, 0);
			this.text.Name = "text";
			this.text.Size = new System.Drawing.Size(200, 21);
			this.text.TabIndex = 0;
			this.text.MouseDown += new System.Windows.Forms.MouseEventHandler(this.TextMouseDown);
			this.text.MouseUp += new System.Windows.Forms.MouseEventHandler(this.TextMouseUp);
			// 
			// groupBox1
			// 
			this.groupBox1.Controls.Add(this.panel1);
			this.groupBox1.Controls.Add(this.list);
			this.groupBox1.Controls.Add(this.panel2);
			this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
			this.groupBox1.Location = new System.Drawing.Point(0, 21);
			this.groupBox1.Name = "groupBox1";
			this.groupBox1.Size = new System.Drawing.Size(200, 219);
			this.groupBox1.TabIndex = 6;
			this.groupBox1.TabStop = false;
			this.groupBox1.Text = "Options";
			// 
			// button1
			// 
			this.button1.Location = new System.Drawing.Point(-80, 200);
			this.button1.Name = "button1";
			this.button1.Size = new System.Drawing.Size(80, 23);
			this.button1.TabIndex = 2;
			this.button1.Text = "button1";
			this.button1.Click += new System.EventHandler(this.Button1Click);
			// 
			// button2
			// 
			this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.button2.ForeColor = System.Drawing.SystemColors.Control;
			this.button2.Image = ((System.Drawing.Image)(resources.GetObject("button2.Image")));
			this.button2.Location = new System.Drawing.Point(0, 0);
			this.button2.Name = "button2";
			this.button2.Size = new System.Drawing.Size(50, 50);
			this.button2.TabIndex = 3123;
			this.toolTip1.SetToolTip(this.button2, "Add folder to list");
			this.button2.Click += new System.EventHandler(this.Button2Click);
			// 
			// button3
			// 
			this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
			this.button3.ForeColor = System.Drawing.SystemColors.Control;
			this.button3.Image = ((System.Drawing.Image)(resources.GetObject("button3.Image")));
			this.button3.Location = new System.Drawing.Point(56, 0);
			this.button3.Name = "button3";
			this.button3.Size = new System.Drawing.Size(60, 50);
			this.button3.TabIndex = 123;
			this.button3.Tag = "0";
			this.toolTip1.SetToolTip(this.button3, "Search for application");
			this.button3.Click += new System.EventHandler(this.Button3Click);
			// 
			// MainForm
			// 
			this.AcceptButton = this.button1;
			this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
			this.ClientSize = new System.Drawing.Size(200, 240);
			this.Controls.Add(this.groupBox1);
			this.Controls.Add(this.text);
			this.Controls.Add(this.button1);
			this.Cursor = System.Windows.Forms.Cursors.Default;
			this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
			this.MaximizeBox = false;
			this.Name = "MainForm";
			this.Opacity = 0.99;
			this.ShowInTaskbar = false;
			this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
			this.Text = "QuickStart";
			this.Resize += new System.EventHandler(this.MainFormResize);
			this.Closing += new System.ComponentModel.CancelEventHandler(this.MainFormClosing);
			this.Load += new System.EventHandler(this.MainFormLoad);
			this.Activated += new System.EventHandler(this.MainFormActivated);
			this.Deactivate += new System.EventHandler(this.MainFormDeactivate);
			this.panel1.ResumeLayout(false);
			this.groupBox1.ResumeLayout(false);
			this.ResumeLayout(false);
		}
		#endregion
		void Button1Click(object sender, System.EventArgs e)
		{			
			if(text.SelectedIndex>=0){
				if(File.Exists(resultDir[text.SelectedIndex]+""))
					//MessageBox.Show(resultDir[text.SelectedIndex]+"");
					Process.Start(resultDir[text.SelectedIndex]+"", "");
				else MessageBox.Show("File is not existed.");
			}else{
				if(text.Enabled){
					currentThread = new Thread(new ThreadStart(doSearch));
					currentThread.Start();
				}
				else currentThread.Abort();
				text.Tag = "";
			}
		}
		
		public void doSearch(){			
			getAppMatch(text.Text);			
		}
		
		public void doSearchAppDir(){
			searchApp();
		}
		
		void MainFormLoad(object sender, System.EventArgs e)
		{
			View();
			load();
			loadDir();
			
			int hWnd = FindWindow( null, this.Text );
			DefWindowProc( hWnd , WM_SHOWWINDOW, 0, 0);
			SendMessage( hWnd, WM_SETHOTKEY, HK_SHIFTA, 0);
		}
		
		string appfilename = "apps.txt";		
		void load(){
			if(File.Exists(appfilename)){
				applist.Items.Clear();
				applist.Items.AddRange( readFile(appfilename).Replace("\r\n",(char)(128)+"").Split((char)(128)) );
			}
		}
		
		string dirfilename = "dirs.txt";
		void loadDir(){
			if(File.Exists(dirfilename)){
				list.Items.Clear();
				list.Items.AddRange( readFile(dirfilename).Replace("\r\n",(char)(128)+"").Split((char)(128)) );
				list.Items.RemoveAt(list.Items.Count-1);
			}
		}
		
		void searchApp(){			
			this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
			this.Text = "QuickStart - Searching for application...";
			string result = "";
			string[] exeFiles;
			string name;
			int count = 0;
			for(int i=0;i<list.Items.Count;i++){								
				exeFiles = getFileList(list.Items[i]+"", "*.exe", true);
				count+=	exeFiles.Length;		
				foreach(string file in exeFiles){
					name = file.Substring( file.LastIndexOf("\\") + 1 );
					result += name+"|"+file+"\r\n";
				}
			}			
			writeFile(appfilename, result);
			load();			
			this.Cursor = System.Windows.Forms.Cursors.Default;
			this.Text = "QuickStart - Searching done("+count+").";
		}
		
		void getAppMatch(string name){
			
			this.Text = "QuickStart - Searching for matched application...";
			
			int startIndex = 0;
			int lastIndex = 0;
			
			text.Items.Clear();
			resultDir.Clear();			
			
			while(startIndex != -1){
				startIndex = applist.FindString(name.Replace("*",""), startIndex+1);
				if(startIndex>=0){
					if(resultDir.IndexOf(applist.Items[startIndex].ToString().Split('|')[1])==-1){
						text.Items.Add(applist.Items[startIndex].ToString().Split('|')[0]);
						resultDir.Add(applist.Items[startIndex].ToString().Split('|')[1]);
					}
				}
								
				
				if(startIndex<lastIndex){
					break;					
				}
				lastIndex = startIndex;				
			}
			
			this.Text = "QuickStart - Searching done("+resultDir.Count+").";
			text.SelectAll();
		}
		
		void View(){
			if(this.Height == 21) this.Height = 240;
			else this.Height = 21;
		}
		
		public static string readFile(string file){
			if(File.Exists(file)){
				StreamReader sr = new StreamReader(file);
				string content = sr.ReadToEnd();
				sr.Close();
				return content;
			}
			return "";
		}
		
		public static void writeFile(string file, string content){			
			StreamWriter sw = new StreamWriter(file);
			sw.Write(content);
			sw.Flush();
			sw.Close();			
		}
		
		public string[] getFileList(string path, string filter, bool includeSubfolder){
			string[] files = new string[0];
			string[] folers = new string[0];
							
			files  = Directory.GetFiles( path, filter );					
			
			ListBox temp = new ListBox();
			temp.Items.AddRange(files);
			temp.Items.AddRange(folers);	
			
			
			if(includeSubfolder){
				string[] directories    = Directory.GetDirectories( path );	
				for(int i=0; i<directories.Length; i++){				
					string[] subFiles = getFileList( directories[i], filter, true );
					temp.Items.AddRange(subFiles);
				}
			}
			files = new string[temp.Items.Count];
			temp.Items.CopyTo( files, 0 );
			return files;
		}
		void Button3Click(object sender, System.EventArgs e)
		{
			if(button3.Tag.ToString() != "1"){
				button3.Tag = "1";
				currentThread = new Thread(new ThreadStart(doSearchAppDir));
				currentThread.Start();
				
			}else{
				currentThread.Abort();
				button3.Tag = "";
				this.Cursor = System.Windows.Forms.Cursors.Default;
			}
				
		}
		
		void Panel2Click(object sender, System.EventArgs e)
		{
			View();
		}
		
			
		void Button2Click(object sender, System.EventArgs e)
		{
			if(browser.ShowDialog()+"" == "OK"){
				writeFile(dirfilename, readFile(dirfilename)+browser.SelectedPath+"\r\n");
				loadDir();
			}
		}
	
		
		void ListKeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
		{
			if( e.KeyCode.ToString() == "Delete" && list.SelectedIndex >= 0){
				string del = list.SelectedItem.ToString();
				writeFile(dirfilename, readFile(dirfilename).Replace(del+"\r\n","") );
				loadDir();
			}
		}
				
		void MainFormResize(object sender, System.EventArgs e)
		{
			list.Height = this.Height -  88;
		}
		
		void MainFormClosing(object sender, System.ComponentModel.CancelEventArgs e)
		{
			currentThread.Abort();
		}		
		
		
		int lastX =0, lastY=0;
		void TextMouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			lastX = e.X;
			lastY = e.Y;
			this.Cursor = Cursors.SizeAll;
		}
		void TextMouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
		{
			this.Location = new Point( this.Location.X + (e.X - lastX) , this.Location.Y + (e.Y - lastY));
			this.Cursor = Cursors.Default;
		}
		void MainFormActivated(object sender, System.EventArgs e)
		{
			while(this.Opacity < 1)
			this.Opacity += 0.0001;
			text.Select();
		}
		
		void MainFormDeactivate(object sender, System.EventArgs e)
		{
			while(this.Opacity > 0.1)
			this.Opacity -= 0.0001;
		}
		
		void MenuItem1Click(object sender, System.EventArgs e)
		{
			this.Close();
		}
		
	}
}
